﻿using System;
using System.Collections.Generic;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Cms.Application.Admin.Presenters;
using Cms.Application.Admin.Views;
using Cms.Domain;
using Cms.Web.Framework.Controls;
using iLib.Web.UI;
using MenuItem = Cms.Domain.MenuItem;

namespace Cms.Web.UI.Admin
{
    public partial class EditMenu : AdminPage, IEditMenuView
    {
        private EditMenuPresenter _presenter;

        #region IEditMenuView Members

        public int MenuID
        {
            get
            {
                if (hidMenuID.Value == "")
                    hidMenuID.Value = QueryString.GetInt32ID("id").ToString();
                return int.Parse(hidMenuID.Value);
            }
        }
        
        public void SetMenuID(int id)
        {
            hidMenuID.Value = id.ToString();
        }

        public string CurrentTab
        {
            get { return tabStrip.CurrentValue; }
        }

        public string Name
        {
            get { return txtName.Text; }
            set { txtName.Text = value; }
        }

        public string Description
        {
            get { return txtDescription.Text; }
            set { txtDescription.Text = value; }
        }
        
        public bool ItemIsActiveWhenSubItemIsActive
        {
            get { return chkItemIsActiveWhenSubItemIsActive.Checked; }
            set { chkItemIsActiveWhenSubItemIsActive.Checked = value; }
        }

        public SubMenuBehaviour SubMenuBehaviour
        {
            get { return rbToggle.Checked ? SubMenuBehaviour.Toggle : SubMenuBehaviour.OpenExclusively; }
            set
            {
                rbToggle.Checked = false;
                rbOpenExclusively.Checked = false;
                if (value == SubMenuBehaviour.Toggle)
                    rbToggle.Checked = true;
                else
                    rbOpenExclusively.Checked = true;
            }
        }
        
        public void SetLocales(IEnumerable<Locale> locales)
        {
            ddlLocales.Items.Clear();
            foreach (Locale l in locales)
                ddlLocales.Items.Add(new ListItem(l.GetTranslation(Localization).Name, l.ID.ToString()));
        }
        
        public int SelectedLocaleID
        {
            get { return int.Parse(ddlLocales.SelectedValue); }
            set { ddlLocales.SelectedValue = value.ToString(); }
        }

        public void SetVersions(IList<MenuVersion> versions, int publishedVersionID)
        {
            ddlVersions.Items.Clear();
            if (versions.Count == 0)
            {
                ddlVersions.Items.Add(new ListItem(GetText(this, "NoMenuVersions"), "-1"));
                lbPublish.Visible = false;
            }
            else
            {
                for (int i = versions.Count - 1; i >= 0; i--)
                {
                    ddlVersions.Items.Add(
                        new ListItem(new DateTime(long.Parse(versions[i].Timestamp)).ToShortDateString() + " " +
                                     new DateTime(long.Parse(versions[i].Timestamp)).ToShortTimeString(),
                                     versions[i].ID.ToString()));
                }
                lbPublish.Visible = true;
            }
            if (publishedVersionID > 0)
            {
                ddlVersions.SelectedValue = publishedVersionID.ToString();
                lbSelectPublishedVersion.Text = ddlVersions.SelectedItem.Text;
                lbSelectPublishedVersion.CommandArgument = publishedVersionID.ToString();
                llNoVersionPublished.Visible = false;
                lbSelectPublishedVersion.Visible = true;
            }
            else
            {
                llNoVersionPublished.Visible = true;
                lbSelectPublishedVersion.Visible = false;
            }
        }
        
        public int SelectedVersionID
        {
            get { return int.Parse(ddlVersions.SelectedValue); }
            set { ddlVersions.SelectedValue = value.ToString(); }
        }
        
        public string Code
        {
            get { return hidCode.Value; }
            set { hidCode.Value = value; }
        }

        public string ContextTranslationFile
        {
            get { return "Admin/Translations/EditMenu.xml"; }
        }
        
        public void SetItems(string menuName, IList<MenuItem> items)
        {
            IList<MenuItem> itemTree = new List<MenuItem>();
            RenderItems(ref itemTree, items);
            rpItems.DataSource = itemTree;
            rpItems.DataBind();
            trNoHits.Visible = items.Count == 0;
        }
        
        public string ActiveItemPrefix
        {
            get { return txtActiveItemPrefix.Text; }
            set { txtActiveItemPrefix.Text = value; }
        }
        
        public int ExtraWrapperSpans
        {
            get { return int.Parse(ddlNumberOfExtraWrapperSpans.SelectedValue); }
            set { ddlNumberOfExtraWrapperSpans.SelectedValue = value.ToString(); }
        }

        #endregion

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            _presenter = new EditMenuPresenter(this);
            int selectedLocaleIndex = ddlLocales.SelectedIndex;
            _presenter.SetLocales();
            ddlLocales.SelectedIndex = selectedLocaleIndex;
            if (!Page.IsPostBack)
            {
                if (MenuID > 0)
                    tabStrip.SelectedValue = Request.QueryString["tab"];
                _presenter.Initialize();
                HeadingIcon = litIcon.Text;
            }
            HeadingText = MenuID > 0
                              ? GetText(this, "EditMenuHeading") + " &mdash; " + Name
                              : GetText(this, "NewMenuHeading");
            lbDeleteMenuItem.OnClientClick = "return cms.Dialogs.ConfirmLinkButton(this, " +
                                             "function (status) { " +
                                             "if (status == 'ok') " +
                                             "cms.Lists.ShowPaneOverlay('itemPaneOverlay');" +
                                             "else " +
                                             "cms.Lists.HidePaneOverlays(); " +
                                             "}, " +
                                             "'" + GetText(this, "DeleteHeader") + "', " +
                                             "'" + GetText(this, "DeleteMessage") + "', " +
                                             "'" + GetText(this, "DeleteOK") + "', " +
                                             "'" + GetText(this, "DeleteCancel") + "', " +
                                             "true);";
        }

        private string GetSaveInfoMessageKey()
        {
            return MenuID > 0 ? "OptionalSaveInfoMessage" : "ForceSaveInfoMessage";
        }
        
        private string GetClientClickScript(AdminTabItem ti)
        {
            return "cms.Edit.ShowTabOverlays(); " +
                   "updateCode(); " +
                   "if (isDirty()) {" +
                   "return cms.Dialogs.Confirm(" +
                   "function (status) { " +
                   "document.getElementById('ctl00_body_hidSaveCode').value = status;" +
                   "document.getElementById('ctl00_tabs_hidSave').value = status;" +
                   "var menuID = document.getElementById('ctl00_tabs_hidMenuID').value;" +
                   "if ((menuID == '' || menuID == '-1') && status != 'ok') " +
                   "cms.Edit.HideTabOverlays(); " +
                   "else " +
                   "__doPostBack('" + ti.UniqueID + "$" + ti.ID + "','');" +
                   "}, " +
                   "'" + GetText(this, "SaveInfoHeader") + "', " +
                   "'" + GetText(this, GetSaveInfoMessageKey()) + "', " +
                   "'" + GetText(this, "SaveInfoOK") + "', " +
                   "'" + GetText(this, "SaveInfoCancel") + "', " +
                   "true, " +
                   "null" +
                   ");" +
                   "}";
        }
        
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            tiProperties.OnClientClick = GetClientClickScript(tiProperties);
            tiCss.OnClientClick = GetClientClickScript(tiCss);
            tiItems.OnClientClick = GetClientClickScript(tiItems);
            hlNewMenuItem.NavigateUrl = "Admin/EditMenuItem.aspx?menuid=" + MenuID +
                                        "&versionid=" + SelectedVersionID +
                                        "&localeid=" + SelectedLocaleID;
            // Re-fetch the properties tab to keep them updated if the user chose not to save changes
            _presenter.RefreshProperties();
        }

        protected override void OnPreRenderComplete(EventArgs e)
        {
            base.OnPreRenderComplete(e);
            ClientScriptProxy.Current.RegisterStartupScript(tabStrip, GetType(),
                                                            "updatePanels",
                                                            "updatePanels('" + tabStrip.SelectedValue + "');", true);
            hlNewMenuItem.Visible = tabStrip.SelectedValue == "items";
            lbSave.Visible = !hlNewMenuItem.Visible;
            upnlButtons.Update();
        }
        
        protected void tabStrip_Click(string value)
        {
            if ((CurrentTab == "properties" && hidSave.Value == "ok") ||
                (CurrentTab == "css" && hidSaveCode.Value == "ok"))
                _presenter.Save();
            if (_presenter.IsValid)
            {
                ClientScriptProxy.Current.RegisterStartupScript(tabStrip, GetType(), "init", "init();", true);
            }
            upnlCss.Update();
            upnlProperties.Update();
            upnlItems.Update();
            upnlTabs.Update();
        }

        protected void lbDragEnd_Click(object sender, EventArgs e)
        {
            if (hidDropzoneID.Value != "")
                _presenter.Move(hidDraggedID.Value, hidDropzoneID.Value, hidDropzonePart.Value);
            UpdateItemPane();
        }
        
        protected void lbDeleteMenuItem_Click(object sender, EventArgs e)
        {
            _presenter.DeleteMenuItem(int.Parse(hidDeleteMenuItemID.Value.Substring(1)));
            UpdateItemPane();
        }
        
        private void UpdateItemPane()
        {
            upnlItems.Update();
            upnlItemsList.Update();
            ClientScriptProxy.Current.RegisterStartupScript(pnlItemActions, GetType(), "initItemList", "initItemList();",
                                                            true);
        }

        protected void lbSave_Click(object sender, EventArgs e)
        {
            _presenter.Save();
            if (_presenter.IsValid)
                Response.Redirect("Menus.aspx");
        }
        
        protected void ddlLocales_IndexChanged(object sender, EventArgs e)
        {
            ClientScriptProxy.Current.RegisterStartupScript(tabStrip, GetType(), "init", "init(); initItemList();", true);
            ddlLocales.SelectedValue = ((DropDownList) sender).SelectedValue;
            _presenter.SaveSelectedLocale();
            _presenter.SetItems();
            upnlItems.Update();
            upnlItemsList.Update();
            upnlTabs.Update();
        }
        
        protected void ddlVersions_IndexChanged(object sender, EventArgs e)
        {
            upnlItems.Update();
        }

        protected void lbPublish_Click(object sender, EventArgs e)
        {
            _presenter.Publish();
        }

        protected void lbSelectPublishedVersion_Click(object sender, EventArgs e)
        {
            ddlVersions.SelectedValue = ((LinkButton) sender).CommandArgument;
            upnlItems.Update();
        }
        
        protected void rpItems_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem)
                return;
            var item = (MenuItem) e.Item.DataItem;
            var litID = (Literal) e.Item.FindControl("litID");
            var litName = (Literal) e.Item.FindControl("litName");
            var litLinksTo = (Literal) e.Item.FindControl("litLinksTo");
            var litTarget = (Literal) e.Item.FindControl("litTarget");
            var litSortIndex = (Literal) e.Item.FindControl("litSortIndex");
            var litActiveForCategory = (Literal) e.Item.FindControl("litActiveForCategory");
            var imgItem = (HtmlImage) e.Item.FindControl("imgItem");
            var litCloser = (Literal) e.Item.FindControl("litCloser");
            litID.Text = @"<div style=""margin-left:" + item.GetLevelInTree() * 16 + @"px;""><span id=""M" + item.ID + @""">";
            litName.Text = item.GetTranslation(SelectedLocaleID).Name;
            switch (item.LinkType)
            {
                case MenuItemLinkType.Page:
                    litLinksTo.Text = item.Page.Name;
                    if (item.Page is ApplicationPage)
                        imgItem.Src = "Admin/Img/icons/page_code.png";
                    else
                        imgItem.Src = "Admin/Img/icons/page.png";
                    break;
                case MenuItemLinkType.Url:
                    litLinksTo.Text = item.GetTranslation(SelectedLocaleID).Url;
                    imgItem.Src = "Admin/Img/icons/page_white_world.png";
                    break;
                default:
                    litLinksTo.Text = GetText(this, "LinksToNothing");
                    imgItem.Src = "Admin/Img/icons/page_white.png";
                    break;
            }
            litCloser.Text = @"</span></div>";
            litTarget.Text = item.Target == null ? GetText(this, "llSelf") : GetText(this, "llBlank");
            litSortIndex.Text = item.SortIndex.ToString();
            litActiveForCategory.Text = item.ActiveForPagesInCategory != null
                                            ? item.ActiveForPagesInCategory.Name
                                            : "&nbsp;";
        }

        private void RenderItems(ref IList<MenuItem> itemTree, IList<MenuItem> items)
        {
            if (items.Count == 0)
                return;
            foreach (MenuItem mi in items)
            {
                itemTree.Add(mi);
                RenderItems(ref itemTree, mi.SubItems);
            }
        }
    }
}